#include<iostream>
#include<string>
#include"Reactor.hpp"
#include"Listener.hpp"
#include"Log.hpp"
#include"Common.hpp"
#include"NetCal.hpp"
using namespace LogModule;
static void Usage(std::string proc)
{
    std::cerr<<"Usage:"<<proc<<"port"<<std::endl;
}

int main(int argc,char* argv[])
{
    if(argc!=2)
    {
        Usage(argv[0]);
        exit(USAGE_ERR);
    }
    EnableConsoleLogStrategy;
    uint16_t port=std::stoi(argv[1]);

    //构建一个Cal的对象,用于协议的计算
    std::shared_ptr<Cal> cal=std::make_shared<Cal>();
    //cal给protocal的request提供计算方法,并且返回response
    std::shared_ptr<Protocol> protocol=std::make_shared<Protocol>([cal](Request& req)->Response{return cal->Execute(req);});
    //构建监听连接的的套接字
    std::shared_ptr<Connection> conn=std::make_shared<Listener>(port);

    //注册函数指针,
    conn->RegisterHandler([&protocol](std::string &inbuffer)->std::string{
        LOG(LogLevel::DEBUG)<<"进入到匿名函数中...";


        //用于返回计算所得值Json格式的报文
        std::string response_str;
        while(true)
        {
            std::string package;

            //在inbuffer中拿出一个报文的数据,并且在inbuffer中删除
            if(!protocol->Decode(inbuffer,&package))
            break;

            //以报文的形式,将package计算所得的Json格式的字符串返回添加
            response_str+=protocol->Excute(package);
        }
        LOG(LogLevel::DEBUG)<<"结束匿名函数中...."<<response_str;

        //最终获得的结果是将inbuffer中Json格式的字符串全部计算,并以Json格式的字符串添加到response_str
        return response_str;
    });

    std::shared_ptr<Reactor> reactor=std::make_shared<Reactor>();
    //添加用于监听的套接字
    reactor->AddConnection(conn);
    
    reactor->Loop();
    return 0;
}